package link.chengguo.orangemall.service.shms.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import link.chengguo.orangemall.comment.SysConstant;
import link.chengguo.orangemall.enums.AllEnum;
import link.chengguo.orangemall.shms.entity.ShmsShopAccount;
import link.chengguo.orangemall.shms.entity.ShmsShopInfo;
import link.chengguo.orangemall.shms.mapper.ShmsShopAccountMapper;
import link.chengguo.orangemall.shms.mapper.ShmsShopInfoMapper;
import link.chengguo.orangemall.shms.service.IShmsShopAccountService;
import link.chengguo.orangemall.shms.service.IShmsShopInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import link.chengguo.orangemall.sys.entity.SysUser;
import link.chengguo.orangemall.sys.service.ISysUserService;
import link.chengguo.orangemall.ums.entity.Sms;
import link.chengguo.orangemall.ums.service.ISmsService;
import link.chengguo.orangemall.ums.service.RedisService;
import link.chengguo.orangemall.util.JsonUtils;
import link.chengguo.orangemall.utils.ValidatorUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * @author yzb
 * @date 2019-12-18
 */

@Service
public class ShmsShopInfoServiceImpl extends ServiceImpl
        <ShmsShopInfoMapper, ShmsShopInfo> implements IShmsShopInfoService {

    @Resource
    private ShmsShopInfoMapper shmsShopInfoMapper;
    @Resource
    private ShmsShopAccountMapper shmsShopAccountMapper;
    @Resource
    private ISysUserService sysUserService;
    @Resource
    private BCryptPasswordEncoder passwordEncoder;

    @Value("${aliyun.sms.day-count:30}")
    private Integer dayCount;

    @Autowired
    private RedisService redisService;
    @Autowired
    private ISmsService smsService;

    @Autowired
    private IShmsShopAccountService shmsShopAccountService;

    @Override
    @Transactional
    public boolean shopVerify(ShmsShopInfo shmsShopInfo){
        if(shmsShopInfo.getAccountStatus().equals(SysConstant.SHOP_ACCOUNR_STATUS_REFUSE_REVIEW) && !ValidatorUtils.isEmpty(shmsShopInfo.getRefuseResson())){
            return shmsShopInfoMapper.updateById(shmsShopInfo)>0?true:false;
        }
        shmsShopInfo.setConfirmDate(new Date());
        //新增店铺管理员信息
        SysUser user = sysUserService.getOne(new QueryWrapper<SysUser>().eq("username", shmsShopInfo.getContactMobile()));
        if(user != null){
            throw new RuntimeException("账号已存在");
        }
        user = new SysUser();
        user.setPlatform(AllEnum.PlatformType.Shop.code());
        user.setUsername(shmsShopInfo.getContactMobile());
        user.setNickName(shmsShopInfo.getContactMobile());
        user.setPassword(shmsShopInfo.getPassword());
        user.setCityCode(shmsShopInfo.getCityCode());
        user.setSupplyId(1L);
        user.setShopId(shmsShopInfo.getId());
        if (sysUserService.saves(user)==false){
            throw new RuntimeException("账号已存在");
        }
        //新增账户信息
        ShmsShopAccount account=new ShmsShopAccount();
        account.setCityCode(shmsShopInfo.getCityCode());
        account.setShopId(shmsShopInfo.getId());
        shmsShopAccountMapper.insert(account);
        this.saveSmsAndSendCode(shmsShopInfo);
        return shmsShopInfoMapper.updateById(shmsShopInfo)>0?true:false;
    }

    @Override
    public boolean createShopInfo(ShmsShopInfo shmsShopInfo) {
        //添加店铺信息
        return shmsShopInfoMapper.insert(shmsShopInfo)>0?true:false;
    }

    @Override
    public boolean resetShopPwd(Long shopId) throws Exception {
        SysUser parm=new SysUser();
        parm.setShopId(shopId);
        parm.setParentId(0L);
        SysUser admin=sysUserService.getOne(new QueryWrapper<>(parm));
        String md5Password = passwordEncoder.encode("123456");
        admin.setPassword(md5Password);
        sysUserService.updateById(admin);
        return true;
    }

    @Override
    public boolean updateShopInfo(ShmsShopInfo shmsShopInfo) throws Exception {
        //更新管理者密码
        if (!StringUtils.isEmpty(shmsShopInfo.getPassword())){
            SysUser user=new SysUser();
            user.setPlatform(AllEnum.PlatformType.Shop.code());//代理用户
            user.setUsername(shmsShopInfo.getContactMobile());
            user.setSupplyId(1L);
            String md5Password = passwordEncoder.encode(shmsShopInfo.getPassword());
            user.setPassword(md5Password);
            //根据手机号更新店铺管理者密码
            QueryWrapper queryWrapper=new QueryWrapper();
            queryWrapper.eq("username",shmsShopInfo.getContactMobile());
            if ( sysUserService.update(user,queryWrapper)==false){
                throw new RuntimeException("密码更新失败");
            }
        }
        //更新代理信息
        shmsShopInfo.setPassword(null);
        shmsShopInfoMapper.updateById(shmsShopInfo);
        return true;
    }

    @Override
    public Page<ShmsShopInfo> customPageList(Integer page,Integer pageSize, ShmsShopInfo paramCondition) {
        Page pp=new Page();
        pp.setCurrent(page);
        pp.setSize(pageSize);
        return shmsShopInfoMapper.customPageList(pp,paramCondition);
    }

    @Override
    public void saveSmsAndSendCode(ShmsShopInfo entity) {
        String phone = entity.getContactMobile();
        checkTodaySendCount(phone);

        Sms sms = new Sms();
        sms.setPhone(phone);

        Map<String, String> params = new HashMap<>();
        params.put("ship_mobile",phone);
        smsService.save(sms, JsonUtils.objectToJson(params));

        //异步调用阿里短信接口发送短信
        CompletableFuture.runAsync(() -> {
            try {
                sms.setTemplateCode("SMS_202335069");
                smsService.sendSmsMsg(sms);
            } catch (Exception e) {
                params.put("err", e.getMessage());
                smsService.save(sms, JsonUtils.objectToJson(params));
                e.printStackTrace();
            }

        });

        // 当天发送验证码次数+1
        String countKey = countKey(phone);
        redisService.increment(countKey, 1L);
        redisService.expire(countKey, 1 * 3600 * 24);
    }
    /**
     * 获取当天发送验证码次数
     * 限制号码当天次数
     *
     * @param phone
     * @return
     */
    private void checkTodaySendCount(String phone) {
        String value = redisService.get(countKey(phone));
        if (value != null) {
            Integer count = Integer.valueOf(value);
            if (count > dayCount) {
                throw new IllegalArgumentException("已超过当天最大次数");
            }
        }

    }

    private String countKey(String phone) {
        return "sms:count:" + LocalDate.now().toString() + ":" + phone;
    }


}
